<template>
  <div v-if="isCompilerPage" class="chat-container" ref="container">
    <div 
      class="chat-button" 
      @mousedown="startDrag"
      @click.stop="toggleChat"
      :style="buttonStyle"
    >
      <van-icon name="chat-o" size="24" color="#fff" />
    </div>
    <div v-if="isOpen" class="chat-window">
      <div class="chat-header">
        <span class="header-title">AI助手</span>
        <div class="header-actions">
          <van-icon name="clock" class="history-icon" @click="showHistory = true" />
        </div>
      </div>
      <div class="chat-content" ref="chatContent">
        <div class="messages" ref="messages">
          <div v-for="(message, index) in messages" :key="index" :class="['message', message.role]">
            <div class="message-content" v-html="message.content" :data-loading="message.showLoadingState"></div>
          </div>
        </div>
        <div class="input-area">
          <van-field
            v-model="inputMessage"
            type="textarea"
            placeholder="输入消息..."
            rows="1"
            autosize
            @keypress.enter.prevent="sendMessage"
          />
          <template v-if="loading">
            <van-button type="danger" size="small" @click="stopChat">停止</van-button>
          </template>
          <template v-else>
            <van-button type="primary" size="small" :loading="loading" @click="sendMessage">发送</van-button>
          </template>
        </div>
      </div>

      <!-- 历史会话弹出层 -->
      <van-popup
        v-model:show="showHistory"
        position="right"
        :style="{ height: '100%', width: '80%' }"
      >
        <div class="history-panel">
          <div class="history-header">
            <span>历史会话</span>
            <div class="header-actions">
              <van-button type="primary" size="small" @click="createNewSession">新会话</van-button>
              <van-icon name="cross" @click="showHistory = false" />
            </div>
          </div>
          <div class="history-list">
            <div 
              v-for="(session, index) in chatHistory" 
              :key="index" 
              class="history-item"
              @click="loadHistorySession(session)"
            >
              <div class="history-title">会话 {{ index + 1 }}</div>
              <div class="history-time">{{ formatTime(session.timestamp) }}</div>
            </div>
          </div>
        </div>
      </van-popup>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { Icon as VanIcon, Field as VanField, Button as VanButton, showToast, Popup as VanPopup } from 'vant'
import { createChatMessage } from '@/api/dify'

const route = useRoute()
const container = ref(null)
const chatContent = ref(null)
// 修复：确保 messages 始终为数组
const messages = ref([]) 
const inputMessage = ref('')
const isCompilerPage = computed(() => route.path.includes('/compiler'))
const isOpen = ref(false)
const loading = ref(false)
const showHistory = ref(false)
const chatHistory = ref([])

// 按钮位置状态
const position = ref({ x: 20, y: 20 })
const buttonStyle = computed(() => ({
  position: 'fixed',
  right: position.value.x + 'px',
  bottom: position.value.y + 'px'
}))

// 拖拽相关变量和方法
let isDragging = false
let startPosition = { x: 0, y: 0 }

const startDrag = (e) => {
  isDragging = true
  startPosition = {
    x: e.clientX - position.value.x,
    y: e.clientY - position.value.y
  }
  e.preventDefault()
  
  // 添加临时事件监听器
  document.addEventListener('mousemove', handleDrag)
  document.addEventListener('mouseup', stopDrag)
}

const handleDrag = (e) => {
  if (!isDragging) return
  
  // 计算新位置
  const windowWidth = window.innerWidth
  const windowHeight = window.innerHeight
  const buttonWidth = 40
  const buttonHeight = 40
  
  let newX = windowWidth - (e.clientX - startPosition.x)
  let newY = windowHeight - (e.clientY - startPosition.y)
  
  // 限制在视窗范围内
  newX = Math.max(20, Math.min(windowWidth - buttonWidth - 20, newX))
  newY = Math.max(20, Math.min(windowHeight - buttonHeight - 20, newY))
  
  position.value = {
    x: newX,
    y: newY
  }
}

const stopDrag = () => {
  isDragging = false
  document.removeEventListener('mousemove', handleDrag)
  document.removeEventListener('mouseup', stopDrag)
}

const toggleChat = () => {
  if (!isDragging) {
    isOpen.value = !isOpen.value
    if (isOpen.value && messages.value.length === 0) {
      // 添加欢迎消息
      messages.value.push({
        role: 'assistant',
        content: '你好！我是你的编码助手'
      })
    }
  }
}

const handleError = (error) => {
  let errorMessage = '发送消息失败，请重试'
  
  if (error.response?.status === 401) {
    errorMessage = '认证失败，请检查API密钥'
  } else if (error.response?.status === 429) {
    errorMessage = '请求过于频繁，请稍后再试'
  } else if (error.message) {
    errorMessage = error.message
  }
  
  showToast(errorMessage)
}

const sendMessage = async () => {
  if (!inputMessage.value.trim() || loading.value) {
    return;
  }
  
  const userMessage = inputMessage.value.trim();
  inputMessage.value = '';
  
  // 添加用户消息
  messages.value.push({
    role: 'user',
    content: userMessage
  });
  
  loading.value = true;
  
  // 创建AI响应消息
  const aiMessage = {
    role: 'assistant',
    content: '正在思考中...',
    showLoadingState: true // 初始设置为 true
  };
  messages.value.push(aiMessage);
  
  try {
    await createChatMessage(userMessage, null, [], (data) => {
      if (data.event === 'message_replace' || data.event === 'agent_message') {
        aiMessage.content = data.answer;
      } else if (data.event === 'done') {
        aiMessage.showLoadingState = false; // 完成时设置为 false
        aiMessage.content = data.answer || aiMessage.content;
      }
      scrollToBottom();
    });
  } catch (error) {
    messages.value.pop(); // 移除 AI 消息
    messages.value.push({
      role: 'assistant',
      content: '抱歉，AI助手遇到了问题，请稍后再试',
      showLoadingState: false
    });
  } finally {
    loading.value = false;
    await scrollToBottom();
    saveMessages();
    if (!loading.value) {
      saveCurrentSession();
    }
  }
};

const stopChat = () => {
  cancelCurrentDialogue(); // 调用API取消对话
  loading.value = false;
  const lastMessage = messages.value[messages.value.length - 1];
  if (lastMessage) {
    lastMessage.showLoadingState = false;
    lastMessage.content = lastMessage.content || '对话已终止';
    lastMessage.isComplete = true;
  }
  saveCurrentSession(); // 保存当前会话到历史记录
};

const saveCurrentSession = () => {
  if (messages.value.length > 1) { // 至少有一问一答才保存
    saveChat(messages.value);
  }
};

const createNewSession = () => {
  if (messages.value.length > 1) { // 如果当前有对话内容，先保存
    saveCurrentSession();
  }
  messages.value = [{
    role: 'assistant',
    content: '你好！我是你的编码助手',
    id: Date.now().toString()
  }];
  saveMessages();
};

const handleMessage = async (message, conversationId, messageId) => {
  try {
    loading.value = true
    let accumulatedAnswer = ''
    
    // 创建AI消息占位
    const aiMessage = {
      role: 'assistant',
      content: '',
      showLoadingState: true
    }
    messages.value.push(aiMessage)
    await scrollToBottom()
    
    // 处理流式响应
    await createChatMessage(message, conversationId, [], (data) => {
      if (data.conversation_id && !conversationId) {
        conversationId = data.conversation_id
      }
      
      if (data.event === 'agent_message' && data.answer) {
        // 只拼接新的内容,避免重复
        let newContent = data.answer.trim()
        if (newContent && !accumulatedAnswer.endsWith(newContent)) {
          accumulatedAnswer += newContent
          aiMessage.content = accumulatedAnswer
          scrollToBottom()
        }
      }
    })
    
    // 回复完成后处理
    aiMessage.showLoadingState = false
    
  } catch (error) {
    console.error('发送消息失败:', error)
    messages.value.pop()
    showToast({
      message: '发送消息失败，请重试',
      type: 'fail',
      duration: 2000
    })
  } finally {
    loading.value = false
    await scrollToBottom()
  }
}

// 格式化消息内容的辅助函数
const formatMessage = (text) => {
  if (!text) return ''
  
  return text
    .trim()
    // 处理代码块
    .replace(/```([\s\S]*?)```/g, (match, code) => {
      const lines = code.trim().split('\n')
      const language = lines[0].trim() // 获取语言标识(如果有)
      const codeContent = language.match(/^[a-zA-Z0-9]+$/) ? lines.slice(1).join('\n') : code
      return `<pre class="code-block"><code class="language-${language}">${codeContent.trim()}</code></pre>`
    })
    // 处理行内代码
    .replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>')
    // 处理标题
    .replace(/### (.*?)(?=\n|$)/g, '<h3>$1</h3>')
    .replace(/## (.*?)(?=\n|$)/g, '<h2>$1</h2>')
    .replace(/# (.*?)(?=\n|$)/g, '<h1>$1</h1>')
    // 处理列表
    .replace(/^\s*[-*]\s+(.*)$/gm, '<li>$1</li>')
    .replace(/(<li>.*<\/li>\n?)+/g, '<ul>$&</ul>')
    // 处理强调
    .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
    .replace(/\*(.*?)\*/g, '<em>$1</em>')
    // 处理链接
    .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>')
    // 处理换行,保留段落格式
    .replace(/\n\n+/g, '</p><p>')
    .replace(/\n/g, '<br>')
    // 确保段落包裹
    .replace(/^(.+)$/, '<p>$1</p>')
}

// 滚动到底部的优化实现
const scrollToBottom = () => {
  nextTick(() => {
    const messagesContainer = document.querySelector('.messages');
    if (messagesContainer) {
      // 使用 requestAnimationFrame 确保在下一帧执行滚动
      requestAnimationFrame(() => {
        messagesContainer.scrollTo({
          top: messagesContainer.scrollHeight,
          behavior: 'smooth'
        });
      });
    }
  });
}

// 保存消息到本地存储
const saveMessages = () => {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(messages.value))
}

// 添加消息持久化
const STORAGE_KEY = 'dify-chat-messages'

onMounted(() => {
  // 恢复历史消息
  const savedMessages = localStorage.getItem(STORAGE_KEY)
  if (savedMessages) {
    try {
      const parsed = JSON.parse(savedMessages)
      // 修复：确保 parsed 是数组
      messages.value = Array.isArray(parsed) ? parsed : []
    } catch (e) {
      console.error('恢复消息历史失败:', e)
      messages.value = []
    }
  } else {
    messages.value = []
  }
  
  // 加载时恢复上次保存的位置
  const savedPosition = localStorage.getItem('difyButtonPosition')
  if (savedPosition) {
    try {
      position.value = JSON.parse(savedPosition)
    } catch (e) {
      console.error('恢复位置失败:', e)
    }
  }

  // 恢复历史会话
  const savedHistory = localStorage.getItem('difyChatHistory')
  if (savedHistory) {
    try {
      chatHistory.value = JSON.parse(savedHistory)
    } catch (e) {
      console.error('恢复历史会话失败:', e)
    }
  }
})

// 监听消息变化，保存到本地存储
watch(messages, (newMessages) => {
  // 修复：只保存数组
  if (Array.isArray(newMessages)) {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(newMessages))
  }
}, { deep: true })

watch(chatHistory, (newHistory) => {
  localStorage.setItem('difyChatHistory', JSON.stringify(newHistory))
}, { deep: true })

onUnmounted(() => {
  // 保存按钮位置
  localStorage.setItem('difyButtonPosition', JSON.stringify(position.value))
})

// 加载历史会话
const loadHistorySession = (session) => {
  messages.value = session.messages
  showHistory.value = false
}

// 格式化时间
const formatTime = (timestamp) => {
  const date = new Date(timestamp)
  return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}`
}
</script>

<style lang="scss" scoped>
.chat-container {
  position: fixed;
  z-index: 999;
}

.chat-button {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: linear-gradient(135deg, #4CAF50, #2196F3);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  transition: transform 0.2s;
}

.chat-button:active {
  transform: scale(0.95);
}

.chat-window {
  position: fixed;
  bottom: 80px;
  left: 0;
  right: 0;
  height: calc(100vh - 120px);
  background: #fff;
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  animation: slideUp 0.3s ease-out;
}

.chat-header {
  padding: 16px;
  background: linear-gradient(135deg, #4CAF50, #2196F3);
  border-radius: 16px 16px 0 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-title {
  color: #fff;
  font-size: 18px;
  font-weight: 500;
}

.header-actions {
  display: flex;
  gap: 16px;
}

.history-icon {
  color: #fff;
  font-size: 20px;
}

.chat-content {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  background: #f5f5f5;
}

.messages {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.message {
  max-width: 85%;
  padding: 12px;
  border-radius: 12px;
  font-size: 15px;
  line-height: 1.5;
}

.message.user {
  align-self: flex-end;
  background: #e3f2fd;
  margin-left: auto;
}

.message.assistant {
  align-self: flex-start;
  background: #fff;
  margin-right: auto;
}

@keyframes slideUp {
  from {
    transform: translateY(100%);
  }
  to {
    transform: translateY(0);
  }
}

.chat-container {
  z-index: 999999;
  pointer-events: auto;
}

.chat-button {
  width: 40px;
  height: 40px;
  border-radius: 20px;
  background-color: #1C64F2;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: move;
  transition: transform 0.2s;
  user-select: none;
}

.chat-button:hover {
  transform: scale(1.05);
}

.chat-window {
  position: fixed;
  right: 20px;
  bottom: 80px;
  width: 380px;
  height: 600px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.chat-header {
  height: 40px;
  background-color: #f5f5f5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  user-select: none;
}

.header-actions {
  display: flex;
  gap: 8px;
}

.chat-header .van-icon {
  cursor: pointer;
  padding: 4px;
}

.chat-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
}

.message {
  margin-bottom: 16px;
  display: flex;
  flex-direction: column;
}

.message.user {
  align-items: flex-end;
}

.message.assistant {
  align-items: flex-start;
}

.message-content {
  max-width: 80%;
  padding: 12px;
  border-radius: 8px;
  background-color: #f5f5f5;
  word-break: break-word;
}

.message.assistant .message-content {
  p {
    margin: 0;
  }
  
  .loading-tip {
    color: var(--text-color-secondary);
    font-size: 14px;
    margin-top: 8px;
  }
}

/* 代码块样式 */
:deep(.code-block) {
  margin: 8px 0;
  padding: 12px;
  background-color: #1e1e1e;
  border-radius: 4px;
  overflow-x: auto;
}

:deep(.code-block code) {
  color: #d4d4d4;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 14px;
  line-height: 1.5;
}

/* 行内代码样式 */
:deep(.inline-code) {
  padding: 2px 4px;
  background-color: rgba(0, 0, 0, 0.1);
  border-radius: 3px;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 14px;
}

/* 标题样式 */
:deep(h1), :deep(h2), :deep(h3) {
  margin: 16px 0 8px;
  font-weight: 600;
  line-height: 1.4;
}

:deep(h1) { font-size: 1.5em; }
:deep(h2) { font-size: 1.3em; }
:deep(h3) { font-size: 1.1em; }

/* 列表样式 */
:deep(ul) {
  margin: 8px 0;
  padding-left: 20px;
}

:deep(li) {
  margin: 4px 0;
  line-height: 1.5;
}

/* 链接样式 */
:deep(a) {
  color: #1C64F2;
  text-decoration: none;
  
  &:hover {
    text-decoration: underline;
  }
}

/* 段落样式 */
:deep(p) {
  margin: 8px 0;
  line-height: 1.6;
}

/* 用户消息中的特殊样式 */
.message.user .message-content {
  background-color: #1C64F2;
  color: white;

  :deep(.inline-code) {
    background-color: rgba(255, 255, 255, 0.2);
  }
  
  :deep(a) {
    color: white;
  }

  :deep(.code-block) {
    background-color: rgba(0, 0, 0, 0.3);
  }
}

.typing {
  display: flex;
  align-items: center;
  gap: 4px;
}

.typing::after {
  content: '';
  width: 4px;
  height: 4px;
  background-color: currentColor;
  border-radius: 50%;
  animation: typing 1s infinite;
}

.input-area {
  padding: 12px;
  border-top: 1px solid #eee;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  background-color: white;
}

.input-area .van-field {
  flex: 1;
}

@keyframes typing {
   0%, 60%, 100% { opacity: 0; }
   30% { opacity: 1; }
}

/* 历史会话样式 */
.history-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.history-header {
  height: 40px;
  background-color: #f5f5f5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  user-select: none;
}

.history-list {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
}

.history-item {
  padding: 12px;
  border-bottom: 1px solid #eee;
  cursor: pointer;
}

.history-title {
  font-weight: 600;
}

.history-time {
  font-size: 0.9em;
  color: #888;
}
</style>
